package com.ygqh.baby.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.foxinmy.weixin4j.util.StringUtil;
import com.ygqh.baby.ao.*;
import com.ygqh.baby.constant.RedisConstant;
import com.ygqh.baby.handler.HolidayNoticeHandler;
import com.ygqh.baby.mapper.YgPromotionMapper;
import com.ygqh.baby.mapper.YgSkuMapper;
import com.ygqh.baby.model.*;
import com.ygqh.baby.po.*;
import com.ygqh.baby.po.YgPromotionExample.Criteria;
import com.ygqh.baby.redis.RedisDao;
import com.ygqh.baby.service.*;
import com.ygqh.baby.utils.DateConvertUtils;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import java.math.BigDecimal;
import java.util.*;

@Service
public class YgPromotionServiceImpl implements YgPromotionService {

    @Autowired
    private YgPromotionMapper ygPromotionMapper;
    @Autowired
    private YgProductService ygProductService;
    @Autowired
    private YgSkuService ygSkuService;
    @Autowired
    private YgSkuMapper ygSkuMapper;
    @Autowired
    private YgProductImagesService ygProductImagesService;
    @Autowired
    private RedisDao redisDao;
    @Autowired
    private YgBmdismService ygBmdismService;
    @Autowired
    private YgProductBookService ygProductBookService;
    @Autowired
    private YgCouponService ygCouponService;
    @Autowired
    private YgProductPackV2Service ygProductPackV2Service;
    @Autowired
    private YgBargainService ygBargainService;

    @Override
    public List<YgPromotion> find(Long supplierId, PromotionStatus pStatus, PromotionType pType, Date startDate, Date endDate, String q) {
        List<YgPromotion> list = ygPromotionMapper.selectSuper(null, supplierId, pStatus == null ? null : pStatus.name(), pType, startDate, endDate, q);
        return list;
    }

    @Override
    public int findCount() {
        YgPromotionExample example = new YgPromotionExample();
        example.createCriteria().andStatusNotEqualTo(DataStatus.Delete.name());
        return ygPromotionMapper.countByExample(example);
    }

    @Override
    public YgPromotion findById(Long id) {
        return ygPromotionMapper.selectByPrimaryKey(id);
    }

    public int save(YgPromotion ygPromotion) {
        return ygPromotionMapper.insertSelective(ygPromotion);
    }

    public int update(YgPromotion ygPromotion) {
        return ygPromotionMapper.updateByPrimaryKeySelective(ygPromotion);
    }

    @Override
    public ResultSet<YgPromotion> search(QueryInfo queryInfo, Long supplierId, PromotionStatus pStatus, PromotionType pType, Date startDate, Date endDate,
                                         String q) {
        List<YgPromotion> list = ygPromotionMapper.selectSuper(queryInfo, supplierId, pStatus == null ? null : pStatus.name(), pType, startDate, endDate, q);
        int count = ygPromotionMapper.countSuper(supplierId, pStatus == null ? null : pStatus.name(), pType, startDate, endDate, q);
        ResultSet<YgPromotion> resultSet = new ResultSet<YgPromotion>(count, list);
        return resultSet;
    }

    @Override
    public int deleteSoft(Long[] ids) {
        Assert.notEmpty(ids);
        int count = 0;
        for (Long id : ids) {
            YgPromotion ygPromotion = this.findById(id);
            ygPromotion.setStatus(DataStatus.Delete);
            count += ygPromotionMapper.updateByPrimaryKeySelective(ygPromotion);
        }

        return count;
    }

    @Override
    public int deleteSoft(Long id) {
        return this.deleteSoft(new Long[]{id});
    }


    public int saveOrUpdate(YgPromotion ygPromotion) {
        int r = 0;
        if (ygPromotion.getId() != null) {
            r = this.update(ygPromotion);
        } else {
            r = this.save(ygPromotion);
        }
        return r;
    }

    @Override
    public List<YgPromotionItemModel> findPromotionItemList(PromotionType pType, BigDecimal limitPrice) {
        return findPromotionItemList(pType, limitPrice, SalesPlatform.Yiigoo);
    }

    @Override
    public List<YgPromotionItemModel> findPromotionItemList(PromotionType pType, BigDecimal limitPrice, SalesPlatform salesPlatform) {
        String[] platformNos = getPlatformNos(salesPlatform);
        return ygPromotionMapper.selectPromotionItemList(pType != null ? pType.name() : null, DateConvertUtils.format(new Date()), limitPrice, platformNos);
    }

    @Override
    public List<YgPromotion> findPromotionBySkuId(Long skuId, PromotionType pType, BigDecimal limitPrice) {
        return findPromotionBySkuId(skuId, pType, limitPrice, SalesPlatform.Yiigoo);
    }

    @Override
    public List<YgPromotion> findPromotionBySkuId(Long skuId, PromotionType pType, BigDecimal limitPrice, SalesPlatform salesPlatform) {
        YgSku sku = ygSkuService.findById(skuId);
        String[] platformNos = getPlatformNos(salesPlatform);
        return ygPromotionMapper.selectPromotionByProductId(sku.getProductId(), pType != null ? pType.name() : null, DateConvertUtils.format(new Date()),
                limitPrice, platformNos);
    }

    @Override
    public Message addPromotion(Long supplierId, String promotionTitle, PromotionType promotionType, BigDecimal limitPrice, BigDecimal discountPrice,
                                String productCodes, Boolean useCoupon, String remark, Date startDate, Date endDate, String createBy, String platformNo) {
        /** 加价购已经支持同时存在两种不同的活动，判断逻辑去掉**/
        //        if (!promotionType.equals(PromotionType.ManZeng)) {
//            Boolean validPromotion = this.validPromotion(promotionType, startDate, endDate, null);
//            if (validPromotion) {
//                return Message.error("存在相同日期的活动,请修改日期");
//            }
//        }
        String productIds = null;

        if (!promotionType.equals(PromotionType.ManJian)) {
            productIds = this.addPromotionProduct(promotionType, productCodes, createBy);
        }
        YgPromotion promotion = new YgPromotion();
        promotion.setSupplierId(supplierId);
        promotion.setPromotionTitle(promotionTitle);
        promotion.setPromotionType(promotionType);
        promotion.setLimitPrice(limitPrice);
        promotion.setDiscountPrice(discountPrice);
        promotion.setProductIds(productIds);
        promotion.setUseCoupon(useCoupon);
        promotion.setStartDate(startDate);
        promotion.setEndDate(endDate);
        promotion.setCreateBy(createBy);
        promotion.setCreateTime(new Date());
        promotion.setRemark(remark);
        promotion.setPlatformNo(platformNo);
        int row = this.save(promotion);
        return Message.success(row);
    }

    @Override
    public int updatePromotion(Long promotionId, String promotionTitle, PromotionType promotionType, BigDecimal limitPrice, BigDecimal discountPrice,
                               String productCodes, Boolean useCoupon, String remark, Date startDate, Date endDate, String updateBy, String platformNo) {
        /** 加价购已经支持同时存在两种不同的活动，判断逻辑去掉**/
        //        if (!promotionType.equals(PromotionType.ManZeng)) {
//            Boolean validPromotion = this.validPromotion(promotionType, startDate, endDate, promotionId);
//            if (validPromotion) {
//                return 0;
//            }
//        }
        String productIds = null;
        if (!promotionType.equals(PromotionType.ManJian)) {
            productIds = this.addPromotionProduct(promotionType, productCodes, updateBy);
        }
        YgPromotion promotion = new YgPromotion();
        promotion.setId(promotionId);
        promotion.setPromotionTitle(promotionTitle);
        promotion.setLimitPrice(limitPrice);
        promotion.setDiscountPrice(discountPrice);
        promotion.setRemark(remark);
        promotion.setStartDate(startDate);
        promotion.setEndDate(endDate);
        promotion.setProductIds(productIds);
        promotion.setUseCoupon(useCoupon);
        promotion.setUpdateBy(updateBy);
        promotion.setUpdateTime(new Date());
        promotion.setPlatformNo(platformNo);
        return this.update(promotion);
    }

    @Override
    public String addPromotionProduct(PromotionType promotionType, String productCodes, String handler) {
        String[] allProductCodes = productCodes.split(",");
        List<String> newProductIds = new ArrayList<String>();
        List<String> hasProductIds = new ArrayList<String>();
        //
        // 已存在的
        List<YgProduct> gifts = ygProductService.findGiftByProductCodes(allProductCodes, promotionType);

        List<String> newProductCodes = new ArrayList<String>();

        for (String str : allProductCodes) {
            newProductCodes.add(str);
        }
        for (YgProduct gift : gifts) {
            hasProductIds.add(gift.getId().toString());

            Iterator it = newProductCodes.iterator();
            while (it.hasNext()) {

                String str = (String) it.next();
                if (str.equals(gift.getProductCode())) {
                    it.remove();
                }

                // 将普通商品的SKU信息更新到促销商品中
                List<YgSku> skuList = ygSkuMapper.selectByProductCode(gift.getProductCode(), PromotionType.Ordinary);
                // 循环SKU
                for (YgSku ygSku : skuList) {
                    // 判断促销商品中是否含有此SKu
                    YgSku cuxiaosku = ygSkuService.findBySkuCode(ygSku.getSkuCode(), promotionType);
                    if (cuxiaosku != null) {// 更新
                        YgSku record = new YgSku();
                        record.setStatus(ygSku.getStatus());
                        record.setSizeName(ygSku.getSizeName());
                        YgSkuExample example = new YgSkuExample();
                        example.createCriteria().andSkuCodeEqualTo(ygSku.getSkuCode()).andProductIdEqualTo(gift.getId());
                        ygSkuMapper.updateByExampleSelective(record, example);

                    } else if (ygSku.getStatus().equals(DataStatus.Valid)) {// 插入
                        YgSku sku = new YgSku();
                        sku.setSkuCode(ygSku.getSkuCode());
                        sku.setProductId(gift.getId());
                        sku.setSizeName(ygSku.getSizeName());
                        sku.setSalesPrice(ygSku.getSalesPrice());
                        sku.setSourceSalesPrice(gift.getProductSalePrice());
                        sku.setCreateTime(new Date());
                        sku.setCreateBy(handler);
                        ygSkuService.save(sku);
                    }

                }
            }
        }

        if (newProductCodes.size() == 0) {
            return StringUtils.join(hasProductIds, ",");
        }
        List<YgProduct> products = ygProductService.findByProductCodes((String[]) newProductCodes.toArray(new String[newProductCodes.size()]),
                PromotionType.Ordinary);
        for (YgProduct goods : products) {
            YgProduct product = new YgProduct();
            product.setProductCode(goods.getProductCode());
            product.setProductName(goods.getProductName());
            product.setProductOriginalPrice(goods.getProductOriginalPrice());
            product.setProductSalePrice(goods.getProductSalePrice());
            product.setProductType(goods.getProductType());
            product.setBrandId(goods.getBrandId());
            product.setGroupId(goods.getGroupId());
            product.setCategoryId(goods.getCategoryId());
            product.setSupplierId(goods.getSupplierId());
            product.setStyleId(goods.getStyleId());
            product.setUnitName(goods.getUnitName());
            product.setDetailImagePath(goods.getDetailImagePath());
            product.setShortName(goods.getShortName());
            product.setCreateTime(new Date());
            product.setCreateBy(handler);
            product.setSaleStatus(ProductStatus.OnSale);
            product.setPromotionType(promotionType);

            int row = ygProductService.save(product);

            if (goods.getYgSkus() != null) {
                List<YgSku> skuList = new ArrayList<YgSku>();

                for (YgSku ygSku : goods.getYgSkus()) {
                    YgSku sku = new YgSku();
                    sku.setSkuCode(ygSku.getSkuCode());
                    sku.setProductId(product.getId());
                    sku.setSizeName(ygSku.getSizeName());
                    sku.setSalesPrice(ygSku.getSalesPrice());
                    sku.setSourceSalesPrice(goods.getProductSalePrice());
                    sku.setCreateTime(new Date());
                    sku.setCreateBy(handler);
                    skuList.add(sku);
                }

                ygSkuService.addSkuInBatch(skuList);
            }
            if (goods.getProductImages() != null) {

                List<YgProductImages> imageList = new ArrayList<YgProductImages>();

                for (YgProductImages productImages : goods.getProductImages()) {
                    YgProductImages image = new YgProductImages();
                    image.setImagePath(productImages.getImagePath());
                    image.setIsMain(productImages.getIsMain());
                    image.setProductId(product.getId());
                    image.setSortNum(productImages.getSortNum());
                    imageList.add(image);
                }
                ygProductImagesService.saveBatch(imageList);
            }

            newProductIds.add(product.getId().toString());
        }
        hasProductIds.addAll(newProductIds);
        return StringUtils.join(hasProductIds, ",");

    }

    @Override
    public List<YgPromotionModel> findOwnPromotionList(PromotionType pType) {
        return findOwnPromotionList(pType, SalesPlatform.Yiigoo);
    }

    @Override
    public List<YgPromotionModel> findOwnPromotionList(PromotionType pType, SalesPlatform salesPlatform) {
        String[] platformNos = getPlatformNos(salesPlatform);
        return ygPromotionMapper.selectOwnPromotionList(pType, DateConvertUtils.format(new Date()), platformNos);
    }

    @Override
    public List<YgPromotionModel> findJiajiagoPromotionList(Long productId) {
        return findJiajiagoPromotionList(productId, SalesPlatform.Yiigoo);
    }

    @Override
    public List<YgPromotionModel> findJiajiagoPromotionList(Long productId, SalesPlatform salesPlatform) {
        String[] platformNos = getPlatformNos(salesPlatform);
        return ygPromotionMapper.findJiajiagoPromotionList(productId, DateConvertUtils.format(new Date()), platformNos);
    }

    private Boolean validPromotion(PromotionType ptype, Date startDate, Date endDate, Long promotionId) {
        YgPromotionExample example = new YgPromotionExample();
        Criteria criteria = example.createCriteria();
        criteria.andStartDateLessThanOrEqualTo(new Date()).andEndDateGreaterThanOrEqualTo(new Date()).andPromotionTypeEqualTo(ptype.name())
                .andStatusEqualTo("Valid");
        if (promotionId != null) {
            criteria.andIdNotEqualTo(promotionId);
        }

        List<YgPromotion> list = ygPromotionMapper.selectByExample(example);
        if (list != null && list.size() > 0) {
            YgPromotion promotion = list.get(0);
            if (promotion.getStartDate().compareTo(endDate) > 0 || promotion.getEndDate().compareTo(DateConvertUtils.addDay(startDate, -1)) < 0) {
                return false;
            } else {
                return true;
            }
        }
        return false;

    }

    @Override
    public List<YgPromotionModel> findManZengPromotionList(Long productId) {
        return ygPromotionMapper.findManZengPromotionList(productId, DateConvertUtils.format(new Date()));
    }

    @Override
    public List<YgPromotionModel> findManZengPromotionList(Long productId, SalesPlatform salesPlatform) {
        return null;
    }

    @Cacheable(cacheNames = "redis", key = "'promotion:pid_'+#productId")
    @Override
    public Map<String, Object> findOwnPromotionListNotLogin(Long productId, Long brandId) {
        return findOwnPromotionListNotLogin(productId, brandId, SalesPlatform.Yiigoo);
    }


    @Autowired
    private HolidayNoticeHandler holidayNoticeHandler;

    @Cacheable(cacheNames = "redis", key = "'promotion:pid_'+#productId+'_salesPlatform'+#salesPlatform")
    @Override
    public Map<String, Object> findOwnPromotionListNotLogin(Long productId, Long brandId, SalesPlatform salesPlatform) {
        Map<String, Object> map = new HashMap<>();
        /*
        指定商品活动
         */
        // 自选包
        List<YgProductPackModel> packList =
                ygProductPackV2Service.findPackList(productId, DateConvertUtils.getDateStart(new Date()));
        if (packList != null && packList.size() > 0) {
            map.put("pack", packList);
        }
        // 对应普通类型商品id
        Long ordinaryProductId = ygProductService.getOrdinaryProductId(productId);
        if (ordinaryProductId != null && ordinaryProductId.intValue() != productId.intValue()) {
            map.put("oPId", ordinaryProductId);
        }
        // 多买多折活动
        List<BmdismModel> bmdsm = ygBmdismService.findByProductIds(productId);
        if (CollectionUtils.isNotEmpty(bmdsm)) {
            map.put("bmdsm", bmdsm);
        }
        //商品是否能用券
        List<YgCouponModel> couponModels = ygCouponService.findCouponList(true, salesPlatform, productId, brandId);
        if (couponModels != null && couponModels.size() > 0) {
            map.put("Coupon", couponModels);
        }
        // 砍价
        YgBargain bargain = ygBargainService.findBargainByProductId(productId, salesPlatform);
        if (bargain != null) {
            map.put("bargain", bargain);
        }
        /*
        全场活动
         */
        Map<String, List<YgPromotionModel>> qcPrmotionMap = getQuanChangPromotions(salesPlatform);
        if (MapUtils.isNotEmpty(qcPrmotionMap)) {
            map.putAll(qcPrmotionMap);
        }
        /*
         CouponPage信息
          */
        String couponPage = redisDao.get("CouponPage");
        if (StringUtil.isNotBlank(couponPage)) {
            map.put("couponPage", JSONObject.parseObject(couponPage, YgCouponPageModel.class));
        }
        /*
         定金膨胀活动
          */
        YgProductBook productBook = ygProductBookService.findByProductId(productId);
        Date date = DateConvertUtils.getDateStart(new Date());
        if (productBook != null && productBook.inValidBookTime(DateConvertUtils.getDateStart(date))) { // 定金支付有效时间内显示活动信息
            map.put("ProductBook", productBook);
            map.put("currentTimeStamp", date);
        }

        String holidayNoticeImgUrl = holidayNoticeHandler.getHolidayNoticeImgUrl(true);
        if (StringUtil.isNotBlank(holidayNoticeImgUrl)) {
            map.put("holidayNotice", holidayNoticeImgUrl);
        }
        return map;
    }

    private Map<String, List<YgPromotionModel>> getQuanChangPromotions(SalesPlatform salesPlatform) {
        Map<String, List<YgPromotionModel>> dataMap = new HashMap<>();
        List<YgPromotionModel> qcPromotions = this.findOwnPromotionList(null, salesPlatform);
        if (CollectionUtils.isNotEmpty(qcPromotions)) {
            for (YgPromotionModel promotion : qcPromotions) {
                List<YgPromotionModel> modelList = dataMap.get(promotion.getPromotionType().name());
                if (modelList == null) {
                    modelList = new ArrayList<>();
                }
                modelList.add(promotion);
                dataMap.put(promotion.getPromotionType().name(), modelList);
            }
        }
        return dataMap;
    }

    @Override
    public void setManFanCoupon(BigDecimal limitPrice, String couponBatchIds) {
        Map<String, Object> data = new HashMap<>();
        data.put("limitPrice", limitPrice);
        data.put("couponBatchIds", couponBatchIds);
        redisDao.set(RedisConstant.MANFAN_COUPON_KEY, JSON.toJSONString(data), 0);
    }

    @Override
    public Map getManFanCoupon() {
        String jsonString = redisDao.get(RedisConstant.MANFAN_COUPON_KEY);
        return JSON.parseObject(jsonString, Map.class);
    }

    @Override
    public void delManFanCoupon() {
        redisDao.del(RedisConstant.MANFAN_COUPON_KEY);
    }
}
